多页签应用实现了页签栏的切换功能,点击页签可以跳转到相应的页面上。本例中的应用主要使用TabList与PageSlider两个控件,其中TabList用于创建页签导航栏,PageSlider用于页签页面的显示与切换。
设置页签导航栏与页签页面的布局。
在根布局中,设置页签导航页与每一个页签内部页面的布局。本例中“root_layout”为根布局,包含TabList与PageSlider的布局。
为每个页签页面的内容创建不同的页面。本例中除“root_layout”外的四个XML文件分别为四个页签页面的内部显示。
“root_layout.xml”文件示例:
<DirectionalLayout xmlns:ohos=“http://schemas.huawei.com/res/ohos”
ohos:width=“match_parent”
ohos:height=“match_parent”
ohos:background_element=“$media:back”
ohos:orientation=“vertical”>
<TabList
ohos:id=“$+id:tabList”
ohos:width=“match_parent”
ohos:height=“40vp”
ohos:tab_margin=“77vp”
ohos:top_margin=“25vp”/>
<PageSlider
ohos:id=“$+id:rootPage”
ohos:width=“match_parent”
ohos:height=“match_parent”/>
</DirectionalLayout>
在MainAbilitySlice的onStart()代码中调用自定义的initPages()方法。方法内部主要实现设置PageSlider的属性以及页签页面切换时的监听等功能。
private void initPages() {
// 从根页面布局的xml文件中获取到PageSlider
Component tempComponent = myLayout.findComponentById(ResourceTable.Id_rootPage);
if (tempComponent == null) {
return;
}
pageSlider = (PageSlider) tempComponent;
// 为PageSlider添加显示数据,其中PageProvider是自定义的类,继承自PageSliderProvider
pageSlider.setProvider(new PageProvider(this, tabComponents));
// 设置PageSlider的属性
pageSlider.setOrientation(Component.HORIZONTAL);
pageSlider.setSlidingPossible(true);
// 设置PageSlider页面改变时的监听
pageSlider.addPageChangedListener(new PageSlider.PageChangedListener() {
public void onPageSliding(int itemPos, float itemPosOffset, int itemPosOffsetPixels) {
}
public void onPageSlideStateChanged(int state) {
}
public void onPageChosen(int itemPos) {
tabList.selectTab(tabList.getTabAt(itemPos));
}
});
}
// PageProvider的实现
public class PageProvider extends PageSliderProvider {
private static final String TAG = “Information”;
private AbilitySlice slice;
private List<AbstractTabComponent> tabComponents;
public PageProvider(AbilitySlice slice, List<AbstractTabComponent> tabComponents) {
this.slice = slice;
if (tabComponents != null) {
this.tabComponents = tabComponents;
} else {
this.tabComponents = new ArrayList<>();
}
}
public int getCount() {
return tabComponents.size();
}
public Object createPageInContainer(ComponentContainer componentContainer, int position) {
Component component = null;
if (componentContainer == null) {
return component;
}
if (0 <= position && position < tabComponents.size()) {
component = tabComponents.get(position).getRootComponent();
}
componentContainer.addComponent(component);
return component;
}
public void destroyPageFromContainer(ComponentContainer componentContainer, int position, Object obj) {
if (componentContainer == null) {
return;
}
if (obj instanceof Component) {
componentContainer.removeComponent((Component) obj);
}
}
public boolean isPageMatchToObject(Component component, Object o) {
return true;
}
}
// AbstractTabComponent的实现
public abstract class AbstractTabComponent {
protected AbilitySlice slice;
private Component rootComponent;
private String name;
public AbstractTabComponent(AbilitySlice slice, String name) {
super();
this.slice = slice;
this.name = name;
}
public String getName() {
return name;
}
public Component getRootComponent () {
return rootComponent;
}
public void setRootComponent (Component rootComponent) {
this.rootComponent = rootComponent;
}
}
在MainAbilitySlice的onStart()代码中调用自定义的initTabs()方法。该方法用于TabList的配置,主要包括TabList的属性配置,TabList内部页签的创建以及页签项选择时的监听。
private void initTabs() {
// 从根页面布局的xml文件中获取到TabList
tabList = (TabList) myLayout.findComponentById(ResourceTable.Id_tabList);
// 设置TabList的属性与页签项中字体的大小
tabList.setTabTextSize(MyStyles.TAB_HEADER_TEXT_SIZE);
tabList.setTabLength(MyStyles.TAB_HEADER_WIDTH);
tabList.setTabTextAlignment(TextAlignment.CENTER);
tabList.setCentralScrollMode(true);
tabList.setTabTextColors(MyStyles.TAB_HEADER_TEXT_COLOR_NORMAL, MyStyles.TAB_HEADER_TEXT_COLOR_SELECTED);
// 为TabList配置页签项
for (AbstractTabComponent tabComponent : tabComponents) {
TabList.Tab tab = tabList.new Tab(this);
tab.setText(tabComponent.getName());
tab.setTextColor(Color.WHITE);
tab.setTextAlignment(TextAlignment.CENTER);
tab.setTextSize(MyStyles.TAB_HEADER_TEXT_SIZE);
tab.setFocusable(Component.FOCUS_ENABLE);
tab.setFocusChangedListener(tabFocusChangeListener);
tabList.addTab(tab);
}
// 为TabList设置选择页签时的监听,TabListener是自定义的类,继承自TabList.TabSelectedListener
tabList.addTabSelectedListener(new TabListener(this, tabComponents, pageSlider));
// 设置默认选择的页签项
tabList.getTabAt(DEFAULE_INDEX).select();
}
//TabListener的实现
public class TabListener implements TabList.TabSelectedListener {
private final static String TAG = “Information”;
private AbilitySlice slice;
private List<AbstractTabComponent> tabComponents;
private PageSlider pageSlider;
public TabListener(AbilitySlice slice, List<AbstractTabComponent> tabComponents, PageSlider pageSlider) {
this.slice = slice;
this.tabComponents = tabComponents;
this.pageSlider = pageSlider;
}
public void onSelected(TabList.Tab tab) {
if (tab == null) {
return;
}
if (pageSlider != null) {
pageSlider.setCurrentPage(tab.getPosition());
}
}
public void onUnselected(TabList.Tab tab) {
if (tab == null) {
return;
}
}
public void onReselected(TabList.Tab tab) {
}
}
在MainAbilitySlice的onStart()中调用自定义的registerListener()方法。该方法对页面中所有的控件都设置为可获焦属性。
private void registerListener(Component rootComponent) {
if (rootComponent == null) {
return;
}
if (rootComponent instanceof ComponentContainer) {
int childNum = ((ComponentContainer) rootComponent).getChildCount();
for (int index = 0; index < childNum; index++) {
Component child = ((ComponentContainer) rootComponent).getComponentAt(index);
registerListener(child);
}
}
// 将控件设置为可获焦属性
rootComponent.setFocusable(Component.FOCUS_ENABLE);
// 设置控件焦点状态改变时的监听
rootComponent.setFocusChangedListener(focusChangeListener);
}
设置指定控件的默认焦点,对期望获取默认焦点的控件调用setBindStateChangedListener方法。本例中指定的默认焦点是页签导航页中的一个页签,因此对其调用该方法。
tabList.getTabAt(DEFAULE_INDEX).setBindStateChangedListener(new Component.BindStateChangedListener() {
public void onComponentBoundToWindow(Component component) {
tabList.getTabAt(DEFAULE_INDEX).requestFocus();
}
public void onComponentUnboundFromWindow(Component component) {
}
});
方法一:对控件调用setKeyEventListener,设置按键的监听
component.setKeyEventListener(new Component.KeyEventListener()){
public boolean onKeyEvent(Component component, KeyEvent keyEvent) {
if (component.hasFocus()) {
if (keyEvent.isKeyDown()) {
if (keyEvent.getKeyCode() == KeyEvent.KEY_ENTER || keyEvent.getKeyCode() == KeyEvent.KEY_DPAD_CENTER) {
HiLog.info(TAG, LOG_FORMAT, “the key is on enter”);
} else if (keyEvent.getKeyCode() == KeyEvent.KEY_DPAD_LEFT) {
HiLog.info(TAG, LOG_FORMAT, “the key is on left”);
} else if (keyEvent.getKeyCode() == KeyEvent.KEY_DPAD_RIGHT) {
HiLog.info(TAG, LOG_FORMAT, “the key is on right”);
}
}
}
return false;
}
};
方法二:首先对控件调用setClickListener的方法用于设置鼠标点击的监听,然后在AbilitySlice的onKeyUp或者onKeyDown的方法中对当前获取焦点的控件调用形如的simulateClick()方法。
public boolean onKeyUp(int keyCode, KeyEvent ev) {
Window window = getWindow();
if (window == null) {
return super.onKeyUp(keyCode, ev);
}
Optional<Component> optionalComponent = window.getCurrentComponentFocus();
if (optionalComponent.isPresent()) {
Component component = optionalComponent.get();
component.setSelected(true);
if (keyCode == KeyEvent.KEY_DPAD_CENTER || keyCode == KeyEvent.KEY_ENTER) {
component.simulateClick();
}
}
return super.onKeyUp(keyCode, ev);
}